%%%-------------------------------------------------------------------
%%% File    : p17.erl
%%% Author  : Plamen Dragozov <plamen at dragozov.com>
%%% Description : 
%%% If the numbers 1 to 5 are written out in words: 
%%% one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 
%%% letters used in total.
%%% If all the numbers from 1 to 1000 (one thousand) inclusive were 
%%% written out in words, how many letters would be used?
%%%
%%% NOTE: Do not count spaces or hyphens. For example, 342 
%%% (three hundred and forty-two) contains 23 letters and 115 
%%% (one hundred and fifteen) contains 20 letters. The use of "and" 
%%% when writing out numbers is in compliance with British usage.
%%%
%%% Created :  5 Dec 2008
%%%-------------------------------------------------------------------
-module(p17).
-compile(export_all).

%%====================================================================
%% API
%%====================================================================
%%--------------------------------------------------------------------
%% Function: solution(N) -> int()
%% Description:Returns the number of letters in all numbers 
%% up to N inclusive.
%%--------------------------------------------------------------------
solution(N) ->
    sum(N, 0).

%%====================================================================
%% Internal functions
%%====================================================================
%Calculates the sum of the letters in all numbers bellow a starting 
%one
sum(0, Acc) ->
    Acc;
sum(I, Acc) ->
    sum(I-1, Acc + count(I)).


%Returns the number of letters in a number
count(1)->
    3;
count(2) ->
    3;
count(3) ->
    5;
count(4) ->
    4;
count(5) ->
    4;
count(6) ->
    3;
count(7) ->
    5;
count(8) ->
    5;
count(9) ->
    4;
count(10) ->
    3;
count(11) ->
    6;
count(12) ->
    6;
count(13) ->
    8;
count(14) ->
    8;
count(15) ->
    7;
count(16) ->
    7;
count(17) ->
    9;
count(18) ->
    8;
count(19) ->
    8;
count(20) ->
    6;
count(30) ->
    6;
count(40) ->
    5;
count(50) ->
    5;
count(60) ->
    5;
count(70) ->
    7;
count(80) ->
    6;
count(90) ->
    6;
count(N) when N < 1000 andalso N rem 100 =:= 0 ->
    7 + count(N div 100);
count(N) when N < 1000000 andalso N rem 1000 =:= 0 ->
    8 + count(N div 1000);
count(N) when N < 100 ->
    Rem = N rem 10,
    count(N - Rem) + count(N rem 10);
count(N) when N < 1000 ->
    Rem = N rem 100,
    count(N - Rem) + 3 + count(Rem);
count(N) when N < 1000000 ->
    Rem = N rem 1000,
    count(N - Rem) + 3 + count(Rem).
